/**
 * 
 */
package gmu.drr.exercise;

import java.io.*;
import java.util.*;
import org.apache.commons.collections15.*;
import edu.uci.ics.jung.graph.*;
import edu.uci.ics.jung.io.*;
import edu.uci.ics.jung.io.graphml.*;
import gmu.drr.entity.*;
import gmu.drr.entity.structure.*;

/**
 * @author RothmD01
 *
 */
public class BaseIOTest {
	/**
	 * @author RothmD01
	 *
	 */
	class TransformerGraphFromMLMeta implements Transformer<GraphMetadata, DirectedSparseMultigraph<Vertex,Edge> > {

		@Override
		public DirectedSparseMultigraph<Vertex, Edge> transform(
				GraphMetadata arg0) {
			DirectedSparseMultigraph<Vertex, Edge> g;
			g = new DirectedSparseMultigraph<Vertex, Edge>();
			return g;
		}		
	}

	/**
	 * @author RothmD01
	 *
	 */
	class TransformerHyperEdgeFromMLMeta implements Transformer<HyperEdgeMetadata, Edge> {

		@Override
		public Edge transform(
				HyperEdgeMetadata arg0) {
			Edge e;
			e = new Edge();
			// TODO fill in data from the edge metadata
			return e;
		}		
	}
	
	public static final int node_count = 50;
	public static final float node_out_deg = 2;
	public static final int edge_count = (int)(node_count*node_out_deg);

	
	public static final int strlen = 12;
	
	public static final String fname = "testGraphOut.txt";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BaseIOTest foo = new BaseIOTest();
		foo.doIORead();
	}
	

	public void doIORead() {
		Graph<Vertex, Edge> graph = new DirectedSparseMultigraph<Vertex, Edge>();	
		FileReader fRead = null;
		
		try {
			fRead = new FileReader( fname) ;
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		GraphMLReader2<DirectedSparseMultigraph<Vertex, Edge>, Vertex, Edge> graphRd = null;
		graphRd = new GraphMLReader2<DirectedSparseMultigraph<Vertex, Edge>, Vertex, Edge>(
				fRead ,
                new TransformerGraphFromMLMeta(),
                Vertex.getTransformerFromMLMeta(),
                Edge.getTransformerEdgeFromMLMeta(),
                new TransformerHyperEdgeFromMLMeta() );		

		try {
			graph = graphRd.readGraph();
		} catch (GraphIOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println( "Retrieved Graph - Vertex Count: "+graph.getVertexCount());
		System.out.println( "Retrieved Graph - Edge Count: "+graph.getEdgeCount());

		Collection<Vertex> vertColl;

		vertColl = graph.getVertices();
		int ct = 0;
		
		for( Iterator<Vertex> i = vertColl.iterator(); i.hasNext(); ) {
			 Vertex v;
			 v = i.next();
			System.out.println( "Vertex :" + v.idName
			 +": "+v.quince);
			ct += 1;
		}
		
	}

	public void doIOWrite() {
		Vertex[] vertSet = new Vertex[50];
		Edge[] edgeSet = new Edge[edge_count];
		Graph<Vertex, Edge> graph = new DirectedSparseMultigraph<Vertex, Edge>();
		
		Random r = new Random();
		
		System.out.println( "New Graph Initiated");
		System.out.println( "Adding Vertices");

		for( int i = 0; i < node_count / 2; i++ ) {
			if( r.nextDouble() > 0.25 ) {
				DomainVertex vertTmp = new Consumer();
				vertSet[i] = new Vertex();
				vertSet[i].domainVert = vertTmp;
				vertSet[i].domainType = DomainVertexType.CONS;
			} else {
				DomainVertex vertTmp = new ConsumerAggregate();
				vertSet[i] = new Vertex();
				vertSet[i].domainVert = vertTmp;
				vertSet[i].domainType = DomainVertexType.CONS_AGG;
			}
		}
		for( int i = node_count / 2; i < node_count; i++ ) {
			DomainVertex vertTmp = new Item();
			vertSet[i] = new Vertex();
			vertSet[i].domainVert = vertTmp;
			vertSet[i].domainType = DomainVertexType.ITEM;
		}
		for( int i = 0; i < node_count; i++) {
			graph.addVertex(vertSet[i]);
			vertSet[i] = this.makeVertInfo(r, vertSet[i]);
			System.out.println( "Vertex Added: " + i );
		}
		
		for( int i = 0; i < edge_count; i++ ) {
			int j, k;
			j = (int)(r.nextFloat() * node_count );
			k = (int)(r.nextFloat() * node_count );

			edgeSet[i] = new Edge(); 
			edgeSet[i] = this.makeEdgeInfo(r, edgeSet[i]);			
			graph.addEdge(edgeSet[i], vertSet[j], vertSet[k]);
			System.out.println( "Edge Added: "+i+": "+j+", "+k);
		}
		
		GraphMLWriter<Vertex, Edge> graphWr;
		graphWr = new GraphMLWriter<Vertex, Edge>();
		Writer w = null;
		
		Transformer<Vertex, String> vertex_ids = Vertex.getTransformerVertIDs();
		Transformer<Edge, String> edge_ids = Edge.getTransformerEdgeToString();
		
		graphWr.setVertexIDs( vertex_ids );
		graphWr.setEdgeIDs( edge_ids );
		
		Transformer<Vertex, String> vdtDat = Vertex.getTransformerVertDomainTypeDat();
		Transformer<Vertex, String> vqDat = Vertex.getTransformerVertQuinceDat();
		Transformer<Vertex, String> vsDat = Vertex.getTransformerVertSeptDat();


		graphWr.addVertexData("domainType", "domain vertex type", "0", vdtDat );
		graphWr.addVertexData("quince", "vert quince data", "-5.0", vqDat );
		graphWr.addVertexData("sept", "vert sept dat", "-7.0", vsDat );
		
		try {
			w = new FileWriter( fname );
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			graphWr.save(graph, w);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}
	
	Edge makeEdgeInfo(Random r, Edge e) {
		final int aVal = ('a');
		String edgeName;
		char[] edgeChars = new char[ strlen ];
		
		for( int i = 0; i < strlen; i++) {
			int newVal = aVal;
			newVal += r.nextInt(26);
			edgeChars[i] = (char)(newVal);
		}
		edgeName = new String(edgeChars);
		e.idName = edgeName;
		
		return e;
	}
	
	Vertex makeVertInfo(Random r, Vertex v) {
		final int aVal = ('a');
		String vertName;
		char[] vertChars = new char[ strlen ];
		
		for( int i = 0; i < strlen; i++) {
			int newVal = aVal;
			newVal += r.nextInt(26);
			vertChars[i] = (char)(newVal);
		}
		vertName = new String(vertChars);
		v.idName = vertName;
		
		v.quince = r.nextDouble();
		v.sept = r.nextDouble();
		
		return v;
	}

}

